package com.atguigu.demojuc.chap02;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;

//资源类：用于操作缓存数据
class MyCache{
    private Map<String,String> cache = new HashMap<>();

    //读写锁。
    private ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();// 默认非公平锁
    
    public void put(String key,String value){
        readWriteLock.writeLock().lock(); //加写锁
        System.out.println(Thread.currentThread().getName() + "\t" + "---come in key="+key+":value"+value);
        cache.put(key,value);
        System.out.println(Thread.currentThread().getName() + "\t" + "---save cache key="+key+":value"+value);
        readWriteLock.writeLock().unlock(); //释放写锁
    }
    
    public void get(String key){
        readWriteLock.readLock().lock(); //加读锁
        System.out.println(Thread.currentThread().getName() + "\t" + "---get key="+key);
        String value = cache.get(key);
        System.out.println(Thread.currentThread().getName() + "\t" + "---get value="+value);
        readWriteLock.readLock().unlock(); //释放读锁
    }
}

/**
 * 测试 ReentrantReadWriteLock 使用： 适用于 读多 写少的业务场景。  这样在大量读请求时效率比较高。
 *      读写锁特征：
 *          写写不可并发
 *          读写、写读不可并发
 *          读读可以并发
 */
public class ReentrantReadWriteLockDemo {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();

        //5个线程写
        for (int i = 1; i <= 5; i++) {
            String num = String.valueOf(i);
            new Thread(()->{
                myCache.put(num,num);
            },"W-T"+num).start();
        }
        //5个线程读
        for (int i = 1; i <= 5; i++) {
            String num = String.valueOf(i);
            new Thread(()->{
                myCache.get(num);
            },"R-T"+num).start();
        }
    }
}
